package com.junwei.webfluxdemo.controller;

import com.junwei.webfluxdemo.entity.User;
import com.junwei.webfluxdemo.repository.UserRepository;
import com.junwei.webfluxdemo.util.CheckUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.validation.Valid;

/**
 * @ClassName UserController
 * @Description TODO
 * @Author 王军伟
 * @Date 2020/2/24 下午8:57
 */
@Api(value = "用户相关")
@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @ApiOperation(value = "查询所有用户", notes = "flux普通模式")
    @GetMapping("/")
    public Flux<User> getAll() {
        return userRepository.findAll();
    }

    @ApiOperation(value = "查询所有用户", notes = "flux sse模式")
    @GetMapping(value = "/stream/all", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> streamGetAll() {
        return userRepository.findAll();
    }

    @ApiOperation(value = "添加用户")
    @PostMapping("/")
    public Mono<User> createUser(@Valid @RequestBody User user) {
        // spring data jpa中，新增和修改都是save，有id是修改，id为空是新增
        // 根据实际情况 是否设置空
        user.setId(null);
        CheckUtil.checkName(user.getName());
        return userRepository.save(user);
    }

    @ApiOperation(value = "删除用户")
    @DeleteMapping("{id}")
    public Mono<ResponseEntity<Void>> deleteUser(@PathVariable("id") String id) {
        return userRepository.findById(id)
                // 如果需要操作数据，并返回一个Mono这个时候使用flatMap
                // 如果不操作数据，只是转换数据，使用map
                .flatMap(user -> userRepository.delete(user)
                        .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))
                        .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND)));
    }

    @ApiOperation(value = "修改用户")
    @PutMapping("{id}")
    public Mono<ResponseEntity<User>> updateUser(@PathVariable("id") String id,
                                                 @Valid @RequestBody User user) {
        CheckUtil.checkName(user.getName());
        return userRepository.findById(id)
                .flatMap(u -> {
                    u.setId(id);
                    u.setAge(user.getAge());
                    u.setName(user.getName());
                    return userRepository.save(u);
                }).map(u -> new ResponseEntity<>(u, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @ApiOperation(value = "根据id查找用户")
    @GetMapping("{id}")
    public Mono<ResponseEntity<User>> findById(@PathVariable("id") String id) {
        return userRepository.findById(id)
                .map(u -> new ResponseEntity<>(u, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @ApiOperation(value = "根据年龄段查找")
    @GetMapping("age/{start}/{end}")
    public Flux<User> findByAge(@PathVariable("start") int start, @PathVariable("end") int end) {
        return userRepository.findByAgeBetween(start, end);
    }

    @ApiOperation(value = "查找大年龄用户")
    @GetMapping("age")
    public Flux<User> oldUser() {
        return userRepository.oldUser();
    }
}
